package com.robusta.app.model.spreadsheet.loader;

import com.google.common.base.Function;
import com.robusta.app.domain.spreadsheet.Model;
import com.robusta.app.model.spreadsheet.persistence.PersistableField;
import com.robusta.app.model.spreadsheet.persistence.PersistableModel;
import com.robusta.spreadsheet.describe.ColumnInfo;
import com.robusta.spreadsheet.describe.WorkbookInfo;
import com.robusta.spreadsheet.describe.WorksheetInfo;
import com.robusta.spreadsheet.model.Row;
import com.robusta.spreadsheet.model.Workbook;
import com.robusta.spreadsheet.model.exception.WorkbookException;

import java.util.List;
import java.util.Map;

import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newTreeMap;

public class WorkbookInfoDescribedWorkbookContentModelBuilder {
    private WorkbookInfo workbookInfo;
    private Workbook workbook;
    private Map<Integer, PersistableModel> modelByRowNumber = newTreeMap();

    public WorkbookInfoDescribedWorkbookContentModelBuilder(WorkbookInfo workbookInfo, Workbook workbook) {
        this.workbookInfo = workbookInfo;
        this.workbook = workbook;
    }

    public List<Model> build() throws WorkbookException {
        for (WorksheetInfo worksheetInfo : workbookInfo.worksheetsInfo()) {
            for (Row row : workbook.getSheetFor(new WorkbookTemplate.WorksheetTemplate(worksheetInfo.templateInfo()))) {
                mapColumnsToModel(modelToMapFromRow(row.rowIndex()), row, worksheetInfo.columnsInfo());
            }
        }
        return newArrayList(transform(modelByRowNumber.keySet(), new Function<Integer, Model>() {
            @Override
            public Model apply(Integer input) {
                return modelByRowNumber.get(input);
            }
        }));
    }

    private void mapColumnsToModel(PersistableModel model, Row row, List<? extends ColumnInfo> columnInfo) throws WorkbookException {
        for (ColumnInfo info : columnInfo) {
            model.add(new PersistableField(row.getCellByHeaderText(info.spreadsheetHeaderText()).getValue(), info));
        }
    }

    private PersistableModel modelToMapFromRow(int index) {
        if(!modelByRowNumber.containsKey(index)) {
            modelByRowNumber.put(index, new PersistableModel());
        }
        return modelByRowNumber.get(index);
    }
}
